﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Configuration;
using System.Data;
using System.Collections;
using System.IO;
using System.IO.Compression;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;

namespace Utils.DC.Web.UI
{
    /// <summary>
    /// Cac ham dung de lam viec voi cac chuc nang cua web nhu caching
    /// Author: Dao Xuan Trung
    /// Date Modified: 20/01/2010
    /// </summary>
    public class WebUtility
    {
        #region Cac Ham Lam Viec Voi Cache

        /// <summary>
        /// Ham Remove Cache
        /// </summary>
        /// <param name="key">Key cua cache</param>
        public static void RemoveCache(String key)
        {
            HttpRuntime.Cache.Remove(key);
        }

        /// <summary>
        /// Ham dung de them cache co cau hinh thoi gian cache
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="cacheTime"></param>
        public static void InsertCache(String key, object value, DateTime cacheTime)
        {
            HttpRuntime.Cache.Insert(key,value,null,cacheTime,Cache.NoSlidingExpiration);
        }

        /// <summary>
        /// Ham dung de them cache voi thoi gian cache mac dinh, dat trong webconfig
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void InsertCache(String key, object value)
        {
            int cacheTime = Convert.ToInt32(ConfigurationManager.AppSettings["DefaultCacheTime"]);
            HttpRuntime.Cache.Insert(key,value,null,DateTime.Now.AddSeconds(cacheTime),Cache.NoSlidingExpiration);
        }

        /// <summary>
        /// Ham dung de lay ve gia tri cua cache
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetCacheObject(String key)
        {
            return HttpRuntime.Cache.Get(key);
        }
        #endregion

        #region Cac Ham Thao Tac Voi Du Lieu 

        /// <summary>
        /// Ham lay ve duong dan cua 1 trang (tim cac trang cha cua no roi ghep chuoi tao thanh duong dan )
        /// </summary>
        /// <param name="pageID">ID cua trang cha</param>
        /// <param name="dtPageList">Danh sach cac trang</param>
        /// <returns>Chuoi Duong dan</returns>
        public static string GetParentUrl(int pageID, DataTable dtPageList)
        {
            bool isLast = false;
            //Lay ve thong tin cua trang hien tai
            if (pageID != 0)
            {
                DataRow row = dtPageList.Select("FunctionPageID = " + pageID)[0];
                string url = row["FunctionPageAlias"].ToString().Trim() + "/";

                //Lay ve trang cha cua trang hien tai 
                //(trang cha co the null neu day la trang co trang cha la trang chuc nang (functionPage) )
                //Neu ko phai la trang goc thi tiep tuc lay trang cha
                if (row["ParentID"] != null && row["ParentID"].ToString().Trim() != "")
                {
                    int? ParentID = Convert.ToInt32(row["ParentID"]);
                    //DataRow parentRows = dtPageList.Select("FunctionPageID = " + ParentID)[0];
                    url = GetParentUrl(ParentID.Value, dtPageList) + url;
                }
                else
                {
                    isLast = true;
                }

                //Nếu là trang admin
                if (isLast)
                {
                    if (Convert.ToBoolean(row["IsAdmin"]))
                        url = "/admin/" + url;
                    else
                        url = "/" + url;
                }

                //Sau khi lay den trang goc thi tra ve url
                return url;
            }
            else
            {
                return "";
            }
        }


        /// <summary>
        /// Ham lay ve duong dan cua 1 trang (tim cac trang cha cua no roi ghep chuoi tao thanh duong dan )
        /// Tra ve level cua page can lay duong dan
        /// </summary>
        /// <param name="pageID">ID cua trang cha</param>
        /// <param name="dtPageList">Danh sach cac trang</param>
        /// <param name="pageLevel">Bien de xac dinh Level cua trang dang xet. Gia tri dau tien la 1</param>
        /// <returns>Chuoi Duong dan</returns>
        public static string GetParentUrl(int pageID, DataTable dtPageList, ref int pageLevel)
        {
            bool isLast = false;
            //Lay ve thong tin cua trang hien tai
            if (pageID != 0)
            {
                DataRow row = dtPageList.Select("FunctionPageID = " + pageID)[0];
                string url = row["FunctionPageAlias"].ToString().Trim() + "/";

                //Lay ve trang cha cua trang hien tai 
                //(trang cha co the null neu day la trang co trang cha la trang chuc nang (functionPage) )
                //Neu ko phai la trang goc thi tiep tuc lay trang cha
                if (row["ParentID"] != null && row["ParentID"].ToString().Trim() != "")
                {
                    //Neu trang cha ton tai thi tang page Level len them 1
                    pageLevel++;
                    
                    int? ParentID = Convert.ToInt32(row["ParentID"]);
                    //DataRow parentRows = dtPageList.Select("FunctionPageID = " + ParentID)[0];
                    url = GetParentUrl(ParentID.Value, dtPageList, ref pageLevel) + url;
                }
                else
                {
                    isLast = true;
                }

                //Nếu là trang admin
                if (isLast)
                {
                    if (Convert.ToBoolean(row["IsAdmin"]))
                        url = "/admin/" + url;
                    else
                        url = "/" + url;
                }

                //Sau khi lay den trang goc thi tra ve url
                return url;
            }
            else
            {
                return "";
            }
        }

        #endregion

        #region Cac Ham Ghi Log

        public static void WriteError(string error)
        {
            //try
            //{
                FileInfo file = new FileInfo("/error.txt");
                if (!file.Exists)
                {
                    System.IO.File.Create("/error.txt");
                }

                StreamWriter sw = file.AppendText();
                sw.WriteLine(error);
                sw.Close();
            //}
            //catch (IOException ie)
            //{

            //}

        }

        #endregion

        #region Cac Ham ViewState Compress va DeCompress

        public static byte[] Compress(byte[] data) {
            MemoryStream output = new MemoryStream();
            GZipStream gzip = new GZipStream(output, 
                              CompressionMode.Compress, true);
            gzip.Write(data, 0, data.Length);
            gzip.Close();
            return output.ToArray();
        }

          public static byte[] Decompress(byte[] data) {
            MemoryStream input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0;
            GZipStream gzip = new GZipStream(input, 
                              CompressionMode.Decompress, true);
            MemoryStream output = new MemoryStream();
            byte[] buff = new byte[64];
            int read = -1;
            read = gzip.Read(buff, 0, buff.Length);
            while(read > 0) {
              output.Write(buff, 0, read);
              read = gzip.Read(buff, 0, buff.Length);
            }
            gzip.Close();
            return output.ToArray();
          }
        #endregion
    }

    public enum CompressOptions
    {
        GZip,
        Deflate,
        None
    }

    public class WhitespaceFilter : Stream
    {
        private GZipStream _contentGZip;
        private DeflateStream _content_Deflate;
        private Stream _content;
        private CompressOptions _options;

        public WhitespaceFilter(Stream content, CompressOptions options)
        {
            if (options == CompressOptions.GZip)
            {
                this._contentGZip = new GZipStream(content, CompressionMode.Compress);
                this._content = this._contentGZip;
            }
            else if (options == CompressOptions.Deflate)
            {
                this._content_Deflate = new DeflateStream(content, CompressionMode.Compress);
                this._content = this._content_Deflate;
            }
            else
            {
                this._content = content;
            }
            this._options = options;
        }


        public override bool CanRead
        {
            get { return this._content.CanRead; }
        }

        public override bool CanSeek
        {
            get { return this._content.CanSeek; }
        }

        public override bool CanWrite
        {
            get { return this._content.CanWrite; }
        }

        public override void Flush()
        {
            this._content.Flush();
        }

        public override long Length
        {
            get { return this._content.Length; }
        }

        public override long Position
        {
            get
            {
                return this._content.Position;
            }
            set
            {
                this._content.Position = value;
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return this._content.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return this._content.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            this._content.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            byte[] data = new byte[count + 1];
            Buffer.BlockCopy(buffer, offset, data, 0, count);


            string s = System.Text.Encoding.UTF8.GetString(data);
            s = Regex.Replace(s, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
            s = Regex.Replace(s, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
            s = Regex.Replace(s, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);

            byte[] outdata = System.Text.Encoding.UTF8.GetBytes(s);
            this._content.Write(outdata, 0, outdata.GetLength(0));
        }

    }
}
